Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / docs / en / rns-link-api.md

Displaying Raw • View renderedDownload


docs/en/rns-link-api.md dev (c9f60cc5) Text, 7.04 KB

Tc9d1d9# RNS Link API

MeshChatX exposes a generic Reticulum Link transport on the main WebSocket (Ta5d6ff`/ws`). External apps and plugins can open links, run request/response exchanges, send packets, and tear links down without going through NomadNet helpers.

Tc9d1d9## When to use it

Ta5d6ff```
Your app or plugin needs a live RNS Link
|
--> Not NomadNet page browsing
--> Not LXMF messaging
|
--> Use rns.link.* over /ws
or plugin managers rnsLink.*
```

Address peers by destination hash and aspect. Do not invent IP or hostname shortcuts.

Tc9d1d9## Auth

When password auth is enabled, every Ta5d6ff`rns.link.*` client message needs an authenticated session. Same rule as other WebSocket mutators.

Tc9d1d9## Link lifecycle

Ta5d6ff```
Client sends rns.link.open
|
--> MeshChatX finds or opens path to destination
|
--> Link cached under (aspect, destination_hash)
|
--> Optional auto_identify
|
--> success / failure reply on same type + request_id
|
+--> rns.link.request / rns.link.send on the cached link
|
+--> rns.link.close tears down and uncaches
|
+--> disconnect cancels in-flight open / request for that client
```

Cache notes:

Tff7b72- Key is Ta5d6ff`(aspect, destination_hash)`
Tff7b72- Cap is 64 active links
Tff7b72- Idle links expire after about 30 minutes
Tff7b72- Repeated request failures recycle the cached link so the next call re-opens

Tc9d1d9## Client to server

All messages need a unique Ta5d6ff`request_id` so replies can be matched.

| Ta5d6ff`type` | Required fields | Optional | Behaviour |
| ------------------- | --------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------ |
| Ta5d6ff`rns.link.open` | Ta5d6ff`destination_hash`, Ta5d6ff`aspect`, Ta5d6ff`request_id` | Ta5d6ff`auto_identify` | Open or reuse a cached link. Streams Ta5d6ff`phase` then Ta5d6ff`success` / Ta5d6ff`failure`. |
| Ta5d6ff`rns.link.identify` | Ta5d6ff`destination_hash`, Ta5d6ff`aspect`, Ta5d6ff`request_id` | | Call Ta5d6ff`link.identify(local_identity)` on the cached link. |
| Ta5d6ff`rns.link.request` | Ta5d6ff`destination_hash`, Ta5d6ff`aspect`, Ta5d6ff`path`, Ta5d6ff`request_id` | Ta5d6ff`data_b64`, Ta5d6ff`timeout` | Ensure the link is open, then Ta5d6ff`link.request(path, data=…)`. |
| Ta5d6ff`rns.link.send` | Ta5d6ff`destination_hash`, Ta5d6ff`aspect`, Ta5d6ff`payload_b64`, Ta5d6ff`request_id` | | Send a raw packet on the cached link. |
| Ta5d6ff`rns.link.close` | Ta5d6ff`destination_hash`, Ta5d6ff`aspect`, Ta5d6ff`request_id` | | Teardown and uncache the link. |

Field details:

Tff7b72- Ta5d6ff`destination_hash`: hex string of the peer destination
Tff7b72- Ta5d6ff`aspect`: dot-separated RNS app name + sub-aspects, for example Ta5d6ff`microrn.mgmt`
Tff7b72- Ta5d6ff`data_b64` / Ta5d6ff`payload_b64` / reply Ta5d6ff`body_b64`: msgpack payloads, base64-encoded
Tff7b72- Ta5d6ff`path`: request path string on the remote link endpoint
Tff7b72- Ta5d6ff`timeout`: seconds for the request wait

Example open:

Ta5d6ff```Ta5d6ffjson
Tb4b4b4{
Tff7b72"type"Tb4b4b4: Ta5d6ff"rns.link.open"Tb4b4b4,
Tff7b72"destination_hash"Tb4b4b4: Ta5d6ff"aabbccddeeff00112233445566778899aabbccdd"Tb4b4b4,
Tff7b72"aspect"Tb4b4b4: Ta5d6ff"microrn.mgmt"Tb4b4b4,
Tff7b72"request_id"Tb4b4b4: Ta5d6ff"req-1"Tb4b4b4,
Tff7b72"auto_identify"Tb4b4b4: Tff7b72true
Tb4b4b4}
Ta5d6ff```

Example request:

Ta5d6ff```Ta5d6ffjson
Tb4b4b4{
Tff7b72"type"Tb4b4b4: Ta5d6ff"rns.link.request"Tb4b4b4,
Tff7b72"destination_hash"Tb4b4b4: Ta5d6ff"aabbccddeeff00112233445566778899aabbccdd"Tb4b4b4,
Tff7b72"aspect"Tb4b4b4: Ta5d6ff"microrn.mgmt"Tb4b4b4,
Tff7b72"path"Tb4b4b4: Ta5d6ff"/status"Tb4b4b4,
Tff7b72"request_id"Tb4b4b4: Ta5d6ff"req-2"Tb4b4b4,
Tff7b72"data_b64"Tb4b4b4: Tff7b72nullTb4b4b4,
Tff7b72"timeout"Tb4b4b4: T79c0ff15
Tb4b4b4}
Ta5d6ff```

Tc9d1d9## Server to client

Per-`request_id` replies reuse the same Ta5d6ff`type` with a Ta5d6ff`status`:

| Ta5d6ff`status` | Meaning |
| ---------- | -------------------------------------------- |
| Ta5d6ff`phase` | Progress step while opening or requesting |
| Ta5d6ff`progress` | Additional progress detail when available |
| Ta5d6ff`success` | Operation finished |
| Ta5d6ff`failure` | Operation failed (includes an error message) |

Broadcast events (not tied to one Ta5d6ff`request_id`):

| Ta5d6ff`type` | Ta5d6ff`event` | Notes |
| ---------------- | ----------------- | ---------------------- |
| Ta5d6ff`rns.link.event` | Ta5d6ff`packet_received` | Includes Ta5d6ff`payload_b64` |
| Ta5d6ff`rns.link.event` | Ta5d6ff`link_closed` | Cached link removed |

Ta5d6ff```
Inbound packet on a cached link
|
--> Broadcast rns.link.event / packet_received
|
Link torn down or evicted
|
--> Broadcast rns.link.event / link_closed
```

Tc9d1d9## Plugins

Plugins call the same transport through HTTP invoke instead of speaking WebSocket types directly.

Ta5d6ff```
Plugin Worker
|
--> POST /api/v1/plugins/{id}/invoke
method: "callManager"
|
--> PluginManager checks granted managers
|
--> RnsLinkManager open / identify / request / send / close
```

Declare managers in Ta5d6ff`plugin.json`:

| Manager | Maps to |
| ------------------ | ----------------------- |
| Ta5d6ff`rnsLink.open` | Open or reuse link |
| Ta5d6ff`rnsLink.identify` | Identify on cached link |
| Ta5d6ff`rnsLink.request` | Request/response |
| Ta5d6ff`rnsLink.send` | Raw packet send |
| Ta5d6ff`rnsLink.close` | Teardown |

Subscribe to async traffic with:

Ta5d6ff```Ta5d6ffjson
Tb4b4b4{
Tff7b72"permissions"Tb4b4b4: Tb4b4b4{
Tff7b72"hooks"Tb4b4b4: Tb4b4b4[Ta5d6ff"rns.link.event"Tb4b4b4],
Tff7b72"managers"Tb4b4b4: Tb4b4b4[Ta5d6ff"rnsLink.open"Tb4b4b4, Ta5d6ff"rnsLink.identify"Tb4b4b4, Ta5d6ff"rnsLink.request"Tb4b4b4, Ta5d6ff"rnsLink.send"Tb4b4b4, Ta5d6ff"rnsLink.close"Tb4b4b4],
Tff7b72"storage"Tb4b4b4: Ta5d6ff"isolated"Tb4b4b4,
Tff7b72"network"Tb4b4b4: Ta5d6ff"none"
Tb4b4b4}
Tb4b4b4}
Ta5d6ff```

Hook delivery:

Ta5d6ff```
RnsLinkManager event
|
--> PluginManager.dispatch_hook("rns.link.event", …)
|
--> WebSocket plugin.event to the UI
|
--> Plugin Worker on_hook / event handler
```

Tc9d1d9## External app pattern

Ta5d6ff```
Connect to MeshChatX /ws (auth cookie / session as required)
|
--> Send rns.link.open with request_id
|
--> Wait for matching success
|
--> Send rns.link.request or rns.link.send
|
--> Listen for rns.link.event broadcasts
|
--> Send rns.link.close when finished
```

Keep one Ta5d6ff`request_id` per outstanding call. Cancel or ignore replies after you disconnect. MeshChatX cancels in-flight open/request work for that WebSocket client on disconnect.

Tc9d1d9## Limits and failure behaviour

Tff7b72- Missing path or unreachable peer returns Ta5d6ff`failure` on the open/request reply
Tff7b72- After repeated request failures on one cached link, MeshChatX recycles that link
Tff7b72- Idle unused links are swept after about 30 minutes
Tff7b72- Over-cap eviction drops the oldest unused links first

Tc9d1d9## Implementation map

Ta5d6ff```
/ws rns.link.*
|
--> meshchat.py WebSocket dispatch + per-client task tracking
|
--> rns_link_manager.py cache, open, identify, request, send, close
|
--> plugin_manager.py capability wrappers + hook fan-out
```

Tc9d1d9## See also

Tff7b72- [Tff7b72Plugins](Te6edf3plugins.md) for install, grants, and invoke flow
Tff7b72- [Tff7b72Architecture and design](Te6edf3architecture.md) for WebSocket and plugin runtime overview
Tff7b72- [Tff7b72Identities, privacy, and security](Te6edf3identity-and-security.md) for auth and session rules


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────